package cc.iotkit.plugins.mattress.parser;

import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonObject;
import io.vertx.core.parsetools.RecordParser;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;

/**
 * 数据包读取器
 *
 * @author sjg
 */
@Slf4j
public class DataReader {
    public static RecordParser getParser(Vertx vertx, Map<String, Integer> existDevice,Consumer<Buffer> receiveHandler) {
        RecordParser parser = RecordParser.newFixed(4);
        // 设置处理器
        parser.setOutput(new Handler<>() {
            // 表示当前数据长度
            int size = -1;
            byte crc = -1;
            Buffer headBuf = null;

            @Override
            public void handle(Buffer buffer) {
                //-1表示当前还没有长度信息，需要从收到的数据中取出长度
                if (-1 == size) {
                    String str = SocketUtil.bytesToHexString(buffer.getBytes());
                    String headStr = str.substring(0, 4);
                    if (!"abcd".equals(headStr)) {
                        log.error("MSG ERROR: Not start with abcd");
                        return;
                    }
                    log.debug("head信息获取："+str);
                    //取出长度
                    size = buffer.getByte(2);
                    crc = buffer.getByte(3);
                    headBuf = Buffer.buffer(buffer.getBytes());
                    //动态修改长度
                    parser.fixedSizeMode(size);

                } else {
                    //如果size != -1, 说明已经接受到长度信息了，接下来的数据就是protobuf可识别的字节数组
                    byte[] buf = buffer.getBytes();
                    log.debug("data信息获取："+ SocketUtil.bytesToHexString(buf));
                    //校验信息CRC
                    byte realCrc = CRC8.calcCrc8(buf);
                    if(realCrc == crc){
                        receiveHandler.accept(Buffer.buffer(buf));
                        //消息传递
                        if(Objects.nonNull(headBuf)){
                            DataPackage data = DataDecoder.decode(buffer);
                            log.debug("**********************************exis5Device:"+existDevice);
                            if(existDevice.containsKey(data.getAddr()) && existDevice.get(data.getAddr())==1){
                                //判断是否存在
                                byte[] mattressData = headBuf.appendBytes(buf).getBytes();
                                vertx.eventBus().send("mattress.forward",new JsonObject().put("mattress", mattressData));
                                log.debug("head+data信息获取："+
                                        SocketUtil.bytesToHexString(mattressData));
                            }
                        }
                    }else{
                        log.error("MSG ERROR:crc error");
                    }
                    //处理完后要将长度改回
                    parser.fixedSizeMode(4);
                    //重置size变量
                    size = -1;
                    crc = -1;
                    headBuf = null;
                }
            }
        });
        return parser;
    }
}
